package edu.zueb.sport.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;

/**
 * 使用 jackson 封装的 json 的工具类
 *
 * @author fuyonde
 * @date 2022/12/21 11:23
 */
@Slf4j
public class JsonUtils {

    private JsonUtils() {
        throw new IllegalStateException("No permission to create an instance");
    }

    private static ObjectMapper objectMapper;

    static {
        init();
    }

    /** 初始化 ObjectMapper 的一些属性 */
    private static void init() {
        objectMapper = new ObjectMapper();
    }

    /**
     * 将对象转换为 JSON 字符串的辅助方法
     *
     * @param o 要转换为 JSON 字符串的对象
     * @return 如果转换成功，则返回包含 JSON 字符串的 Optional 对象；如果转换失败，则返回空的 Optional 对象
     */
    public static Optional<String> toJson(Object o) {
        // 使用对象映射器尝试将对象转换为 JSON 字符串
        try {
            return Optional.of(objectMapper.writeValueAsString(o));
        } catch (JsonProcessingException e) {
            // 如果发生 JSON 处理异常，记录错误并返回空的 Optional
            log.error("toJsonFail", e);
            return Optional.empty();
        }
    }

    /**
     * 将JSON字符串转换为Java对象的Optional封装
     *
     * @param json 待转换的JSON字符串
     * @param typeReference 类型引用，用于指定转换的目标类型
     * @param <T> 泛型参数，表示转换后的对象类型
     * @return 返回一个Optional封装的转换后的对象如果转换成功，则返回Optional包含该对象；如果转换失败或JSON字符串为null，则返回Optional.empty()
     */
    public static <T> Optional<T> fromJson(String json, TypeReference<T> typeReference) {
        try {
            // 尝试将JSON字符串转换为指定类型的对象，并用Optional封装返回
            return Optional.ofNullable(objectMapper.readValue(json, typeReference));
        } catch (JsonProcessingException e) {
            // 如果发生JSON处理异常，记录错误日志并返回空的Optional
            log.error("toObjectFail", e);
            return Optional.empty();
        }
    }
}
